<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html><head><title>Programming in Lua : 25.1</title>
<link rel="stylesheet" type="text/css" href="pil.css">
</head>
<body>
<p class="warning">
<A HREF="contents.html"><IMG TITLE="Programming in Lua (first edition)" SRC="capa.jpg" ALT="" ALIGN="left"></A>This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.<BR>The third edition targets Lua 5.2 and is available at <A HREF="http://www.amazon.com/exec/obidos/ASIN/859037985X/theprogrammil3-20">Amazon</A> and other bookstores.<BR>By buying the book, you also help to <A HREF="../donations.html">support the Lua project</A>.
</p>
<table width="100%" class="nav">
<tr>
<td width="10%" align="left"><a href="25.html"><img border="0" src="left.png" alt="Previous"></a></td>
<td width="80%" align="center"><a href="contents.html"><font face="Helvetica,Arial,sanserif">
<font color="gray">Programming in </font><font color="blue"> Lua</font>
</font></a></td>
<td width="10%" align="right"><a href="25.2.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
<tr>
<td width="10%" align="left"></td>
<td width="80%" align="center"><a href="contents.html#P4">Part IV. The C API</a>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="contents.html#25">Chapter 25. Extending your Application</a></td>
<td width="10%" align="right"></td></tr>
</table>
<hr/>
<p><h2>25.1 &ndash; Table Manipulation</h2>

<p>Let us adopt that attitude:
Now, we want to configure a background color for the window, too.
We will assume that the final color specification is composed
of three numbers,
where each number is a color component in RGB.
Usually, in C, those numbers are integers in some range
like <em>[0,255]</em>.
In Lua, because all numbers are real,
we can use the more natural range <em>[0,1]</em>.

<p>A naive approach here is to ask the user to set each component
in a different global variable:
<pre>
    -- configuration file for program `pp'
    width = 200
    height = 300
    background_red = 0.30
    background_green = 0.10
    background_blue = 0
</pre>
This approach has two drawbacks:
It is too verbose
(real programs may need dozens of different colors,
for window background, window foreground, menu background, etc.);
and there is no way to predefine common colors,
so that, later,
the user can simply write something like <code>background = WHITE</code>.
To avoid these drawbacks, we will use a table to represent a color:
<pre>
    background = {r=0.30, g=0.10, b=0}
</pre>
The use of tables gives more structure to the script;
now it is easy for the user (or for the application)
to predefine colors for later use in the configuration file:
<pre>
    BLUE = {r=0, g=0, b=1}
    ...
    background = BLUE
</pre>
To get these values in C, we can do as follows:
<pre>
    lua_getglobal(L, "background");
    if (!lua_istable(L, -1))
      error(L, "`background' is not a valid color table");
    
    red = getfield("r");
    green = getfield("g");
    blue = getfield("b");
</pre>
As usual, we first get the value of the global variable <code>background</code>
and ensure that it is a table.
Next, we use <code>getfield</code> to get each color component.
This function is not part of the API;
we must define it, as follows:
<pre>
    #define MAX_COLOR       255
    
    /* assume that table is on the stack top */
    int getfield (const char *key) {
      int result;
      lua_pushstring(L, key);
      lua_gettable(L, -2);  /* get background[key] */
      if (!lua_isnumber(L, -1))
        error(L, "invalid component in background color");
      result = (int)lua_tonumber(L, -1) * MAX_COLOR;
      lua_pop(L, 1);  /* remove number */
      return result;
    }
</pre>
Again, we face the problem of polymorphism:
There are potentially many versions of <code>getfield</code> functions,
varying the key type, value type, error handling, etc.
The Lua API offers a single function, <code>lua_gettable</code>.
It receives the position of the table in the stack,
pops the key from the stack,
and pushes the corresponding value.
Our private <code>getfield</code> assumes that the table is on the top of the stack;
so, after pushing the key (<code>lua_pushstring</code>),
the table will be at index <em>-2</em>.
Before returning, <code>getfield</code> pops the retrieved value from the stack,
to leave the stack at the same level that it was before the call.

<p>We will extend our example a little further
and introduce color names for the user.
The user can still use color tables,
but she can also use predefined names for the more common colors.
To implement this feature,
we need a color table in our C application:
<pre>
    struct ColorTable {
      char *name;
      unsigned char red, green, blue;
    } colortable[] = {
      {"WHITE",   MAX_COLOR, MAX_COLOR, MAX_COLOR},
      {"RED",     MAX_COLOR,   0,   0},
      {"GREEN",     0, MAX_COLOR,   0},
      {"BLUE",      0,   0, MAX_COLOR},
      {"BLACK",     0, 0, 0},
      ...
      {NULL,        0, 0, 0}  /* sentinel */
    };
</pre>

<p>Our implementation will create global variables with the color names
and initialize these variables using color tables.
The result is the same as if the user had the following
lines in her script:
<pre>
    WHITE = {r=1, g=1, b=1}
    RED   = {r=1, g=0, b=0}
    ...
</pre>
The only difference from these user-defined colors is that
the application defines these colors in C,
before running the user script.

<p>To set the table fields,
we define an auxiliary function, <code>setfield</code>;
it pushes the index and the field value on the stack,
and then calls <code>lua_settable</code>:
<pre>
    /* assume that table is at the top */
    void setfield (const char *index, int value) {
      lua_pushstring(L, index);
      lua_pushnumber(L, (double)value/MAX_COLOR);
      lua_settable(L, -3);
    }
</pre>
Like other API functions,
<code>lua_settable</code> works for many different types,
so it gets all its operands from the stack.
It receives the table index as an argument
and pops the key and the value.
The <code>setfield</code> function assumes that before the call
the table is at the top of the stack (index <em>-1</em>);
after pushing the index and the value,
the table will be at index <em>-3</em>.

<p>The <code>setcolor</code> function defines a single color.
It must create a table, set the appropriate fields,
and assign this table to the corresponding global variable:
<pre>
    void setcolor (struct ColorTable *ct) {
      lua_newtable(L);               /* creates a table */
      setfield("r", ct->red);        /* table.r = ct->r */
      setfield("g", ct->green);      /* table.g = ct->g */
      setfield("b", ct->blue);       /* table.b = ct->b */
      lua_setglobal(L, ct->name);    /* `name' = table */
    }
</pre>
The <code>lua_newtable</code> function creates an empty table
and pushes it on the stack;
the <code>setfield</code> calls set the table fields;
finally, <code>lua_setglobal</code> pops the table and
sets it as the value of the global with the given name.

<p>With those previous functions,
the following loop will register all colors in
the application's global environment:
<pre>
    int i = 0;
    while (colortable[i].name != NULL)
      setcolor(&amp;colortable[i++]);
</pre>
Remember that the application must execute this loop
before running the user script.

<p>There is another option for implementing named colors.
Instead of global variables,
the user can denote color names with strings,
writing her settings as <code>background = "BLUE"</code>.
Therefore, <code>background</code> can be either a table or a string.
With this implementation,
the application does not need to do anything before running
the user's script.
Instead, it needs more work to get a color.
When it gets the value of the variable <code>background</code>,
it has to test whether the value has type string,
and then look up the string in the color table:
<pre>
    lua_getglobal(L, "background");
    if (lua_isstring(L, -1)) {
      const char *name = lua_tostring(L, -1);
      int i = 0;
      while (colortable[i].name != NULL &amp;&amp;
             strcmp(colorname, colortable[i].name) != 0)
        i++;
      if (colortable[i].name == NULL)  /* string not found? */
        error(L, "invalid color name (%s)", colorname);
      else {  /* use colortable[i] */
        red = colortable[i].red;
        green = colortable[i].green;
        blue = colortable[i].blue;
      }
    } else if (lua_istable(L, -1)) {
      red = getfield("r");
      green = getfield("g");
      blue = getfield("b");
    } else
        error(L, "invalid value for `background'");
</pre>

<p>What is the best option?
In C programs,
the use of strings to denote options is not a good practice,
because the compiler cannot detect misspellings.
In Lua, however, global variables do not need declarations,
so Lua does not signal any error when
a user misspells a color name.
If the user writes <code>WITE</code> instead of <code>WHITE</code>,
the <code>background</code> variable receives <B>nil</B>
(the value of <code>WITE</code>, a variable not initialized),
and that is all that the application knows:
that <code>background</code> is <B>nil</B>.
There is no other information about what is wrong.
With strings, on the other hand,
the value of <code>background</code> would be the misspelled string;
so, the application can add that information to the error message.
The application can also compare strings regardless of case,
so that a user can write <code>"white"</code>, <code>"WHITE"</code>, or even <code>"White"</code>.
Moreover, if the user script is small
and there are many colors,
it may be odd to register hundreds of colors
(and to create hundreds of tables and global variables)
only for the user to choose a few.
With strings, you avoid this overhead.

<hr/>
<table width="100%" class="nav">
<tr valign="top">
<td width="90%" align="left">
<small>
  Copyright &copy; 2003&ndash;2004 Roberto Ierusalimschy.  All rights reserved.
</small>
</td>
<td width="10%" align="right"><a href="25.2.html"><img border="0" src="right.png" alt="Next"></a></td>
</tr>
</table>


</body></html>

